<template>
  <el-dialog
    v-model="dialogVisible"
    title="AI辅助"
    width="800px"
    :close-on-click-modal="false"
  >
    <div class="ai-assistant-container">
      <div class="ai-assistant-content">
        <div class="messages-container" ref="messagesContainer">
          <div v-for="(message, index) in messages" :key="index" class="message-item" :class="message.role">
            <div class="message-header">
              <span class="role-icon" :class="message.role">
                <el-icon v-if="message.role === 'user'"><User /></el-icon>
                <el-icon v-else-if="message.role === 'assistant'"><ChatDotRound /></el-icon>
                <el-icon v-else><Cpu /></el-icon>
              </span>
              <span class="role-text">{{ getRoleText(message.role) }}</span>
            </div>
            <div class="message-content" :class="{ 'typing': isTyping(message) }">
              <template v-if="message.role === 'reasoning'">
                <div class="thinking-animation">
                  <span class="dot"></span>
                  <span class="dot"></span>
                  <span class="dot"></span>
                </div>
              </template>
              <div v-html="renderMarkdown(message.content)"></div>
            </div>
            <div v-if="message.role === 'assistant'" class="message-actions">
              <el-button 
                type="primary" 
                size="small" 
                @click="extractCode(message)"
                :icon="Document"
              >
                提取代码
              </el-button>
              <el-button 
                type="success" 
                size="small" 
                @click="saveAsSnippet(message)"
                :icon="Collection"
              >
                保存代码段
              </el-button>
            </div>
          </div>
        </div>
        <div class="input-container">
          <el-input
            v-model="question"
            type="textarea"
            :rows="4"
            placeholder="请输入您的问题，例如：如何优化SQL查询？如何解决性能问题？"
            :disabled="loading"
          />
          <div class="ai-assistant-actions">
            <el-button type="primary" @click="sendMessage" :loading="loading">发送</el-button>
            <el-button @click="clearQuestion">清空</el-button>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, watch, nextTick, h } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { createAgentAi } from '@/uses/agentAi'
import { User, ChatDotRound, Cpu, Document, Collection } from '@element-plus/icons-vue'
import MarkdownIt from 'markdown-it'

const props = defineProps({
  sql: {
    type: String,
    default: ''
  },
  queryType: {
    type: Number,
    default: null
  },
  params: {
    type: Array,
    default: () => []
  },
  onSaveSnippet: {
    type: Function,
    default: null
  }
})

const emit = defineEmits(['update:sql'])

const dialogVisible = ref(false)
const question = ref('')
const messagesContainer = ref(null)
const typingMessages = ref(new Set())

const { sendMessage: sendAiMessage, messages, loading, connected } = createAgentAi()

const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  breaks: true
})

// 监听消息变化，自动滚动到底部
watch(messages, async () => {
  await nextTick()
  scrollToBottom()
}, { deep: true })

const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

const show = () => {
  dialogVisible.value = true
  // 显示对话框后滚动到底部
  nextTick(() => {
    scrollToBottom()
  })
}

const getRoleText = (role) => {
  switch (role) {
    case 'user':
      return '用户'
    case 'assistant':
      return 'AI助手'
    case 'reasoning':
      return '思考中'
    default:
      return role
  }
}

const isTyping = (message) => {
  return message.role === 'reasoning' && !typingMessages.value.has(message)
}

const sendMessage = async () => {
  if (!question.value.trim()) {
    ElMessage.warning('请输入问题')
    return
  }
  
  if (!connected.value) {
    ElMessage.warning('AI服务未连接，请稍后再试')
    return
  }
  
  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: question.value
  })
  
  // 发送消息
  sendAiMessage(question.value)
  
  // 清空输入框
  question.value = ''
}

const clearQuestion = () => {
  question.value = ''
  messages.value = [
    {role: 'assistant', content: '你好！我是AI助手,有什么可以帮你的吗?'}
  ]
}

const extractCode = (message) => {
  // 使用正则表达式匹配代码块
  const codeRegex = /```(?:sql)?\n([\s\S]*?)```/g
  const matches = [...message.content.matchAll(codeRegex)]
  
  if (matches.length === 0) {
    ElMessage.warning('未找到可提取的代码')
    return
  }
  
  // 提取所有代码块
  const codeBlocks = matches.map(match => match[1].trim())
  
  // 如果只有一个代码块，直接使用
  if (codeBlocks.length === 1) {
    emit('update:sql', codeBlocks[0])
    ElMessage.success('代码已提取到编辑器')
    return
  }
  
  // 如果有多个代码块，让用户选择
  ElMessageBox.confirm(
    '找到多个代码块，请选择要提取的代码',
    '选择代码',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'info',
      customClass: 'code-select-dialog',
      message: h('div', { class: 'code-select-container' }, [
        h('div', { class: 'code-select-list' }, codeBlocks.map((code, index) => 
          h('div', { 
            class: 'code-select-item',
            onClick: () => {
              emit('update:sql', code)
              ElMessage.success('代码已提取到编辑器')
              ElMessageBox.close()
            }
          }, [
            h('div', { class: 'code-select-header' }, [
              h('span', { class: 'code-index' }, `代码块 ${index + 1}`),
              h('el-button', {
                class: 'preview-btn',
                type: 'text',
                onClick: (e) => {
                  e.stopPropagation()
                  ElMessageBox.alert(code, `代码块 ${index + 1} 预览`, {
                    customClass: 'code-preview-dialog',
                    confirmButtonText: '使用这段代码',
                    callback: () => {
                      emit('update:sql', code)
                      ElMessage.success('代码已提取到编辑器')
                    }
                  })
                }
              }, '预览')
            ]),
            h('pre', { class: 'code-select-content' }, code.substring(0, 100) + (code.length > 100 ? '...' : ''))
          ])
        ))
      ])
    }
  )
}

const saveAsSnippet = (message) => {
  // 使用正则表达式匹配代码块
  const codeRegex = /```(?:sql)?\n([\s\S]*?)```/g
  const matches = [...message.content.matchAll(codeRegex)]
  
  if (matches.length === 0) {
    ElMessage.warning('未找到可保存的代码')
    return
  }
  
  // 提取所有代码块
  const codeBlocks = matches.map(match => match[1].trim())
  
  // 如果只有一个代码块，直接保存
  if (codeBlocks.length === 1) {
    if (props.onSaveSnippet) {
      props.onSaveSnippet(codeBlocks[0])
    }
    return
  }
  
  // 如果有多个代码块，让用户选择
  ElMessageBox.confirm(
    '找到多个代码块，请选择要保存的代码',
    '选择代码',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'info',
      customClass: 'code-select-dialog',
      message: h('div', { class: 'code-select-container' }, [
        h('div', { class: 'code-select-list' }, codeBlocks.map((code, index) => 
          h('div', { 
            class: 'code-select-item',
            onClick: () => {
              if (props.onSaveSnippet) {
                props.onSaveSnippet(code)
              }
              ElMessageBox.close()
            }
          }, [
            h('div', { class: 'code-select-header' }, [
              h('span', { class: 'code-index' }, `代码块 ${index + 1}`),
              h('el-button', {
                class: 'preview-btn',
                type: 'text',
                onClick: (e) => {
                  e.stopPropagation()
                  ElMessageBox.alert(code, `代码块 ${index + 1} 预览`, {
                    customClass: 'code-preview-dialog',
                    confirmButtonText: '保存这段代码',
                    callback: () => {
                      if (props.onSaveSnippet) {
                        props.onSaveSnippet(code)
                      }
                    }
                  })
                }
              }, '预览')
            ]),
            h('pre', { class: 'code-select-content' }, code.substring(0, 100) + (code.length > 100 ? '...' : ''))
          ])
        ))
      ])
    }
  )
}

const renderMarkdown = (content) => {
  return md.render(content)
}

defineExpose({
  show
})
</script>

<style scoped>
.ai-assistant-container {
  padding: 20px;
}

.ai-assistant-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  height: 500px;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  scroll-behavior: smooth;
}

.message-item {
  margin-bottom: 15px;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.message-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.message-header {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  font-weight: bold;
}

.role-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  margin-right: 8px;
}

.role-icon.user {
  background-color: #e6f7ff;
  color: #1890ff;
}

.role-icon.assistant {
  background-color: #e6f7ff;
  color: #1890ff;
}

.role-icon.reasoning {
  background-color: #f9f0ff;
  color: #722ed1;
}

.role-text {
  font-size: 14px;
  color: #666;
}

.message-item.user {
  background-color: #e6f7ff;
  margin-left: 20px;
}

.message-item.assistant {
  background-color: #f0f9ff;
  margin-right: 20px;
  border-left: 4px solid #1890ff;
}

.message-item.reasoning {
  background-color: #f9f0ff;
  margin-right: 20px;
  border-left: 4px solid #722ed1;
}

.message-content {
  white-space: pre-wrap;
  line-height: 1.6;
  position: relative;
  
  :deep(p) {
    margin: 0.5em 0;
  }
  
  :deep(pre) {
    background-color: #f5f7fa;
    padding: 12px;
    border-radius: 4px;
    overflow-x: auto;
    margin: 0.5em 0;
  }
  
  :deep(code) {
    font-family: monospace;
    font-size: 14px;
  }
  
  :deep(ul), :deep(ol) {
    padding-left: 2em;
    margin: 0.5em 0;
  }
  
  :deep(blockquote) {
    border-left: 4px solid #dcdfe6;
    padding-left: 1em;
    margin: 0.5em 0;
    color: #666;
  }
  
  :deep(table) {
    border-collapse: collapse;
    width: 100%;
    margin: 0.5em 0;
    
    th, td {
      border: 1px solid #dcdfe6;
      padding: 8px;
    }
    
    th {
      background-color: #f5f7fa;
    }
  }
}

.message-content.typing {
  min-height: 20px;
}

.thinking-animation {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 8px;
}

.thinking-animation .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #722ed1;
  animation: thinking 1.4s infinite ease-in-out;
}

.thinking-animation .dot:nth-child(1) {
  animation-delay: 0s;
}

.thinking-animation .dot:nth-child(2) {
  animation-delay: 0.2s;
}

.thinking-animation .dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes thinking {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ai-assistant-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.message-actions {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

.code-select-dialog {
  .code-select-container {
    max-height: 400px;
    overflow-y: auto;
  }
  
  .code-select-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  
  .code-select-item {
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s ease;
    
    &:hover {
      border-color: #1890ff;
      background-color: #f0f9ff;
    }
  }
  
  .code-select-header {
    padding: 8px 12px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #dcdfe6;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .code-index {
    font-weight: bold;
  }
  
  .preview-btn {
    padding: 0;
  }
  
  .code-select-content {
    padding: 12px;
    margin: 0;
    white-space: pre-wrap;
    font-family: monospace;
    font-size: 14px;
    line-height: 1.5;
    background-color: #fafafa;
    max-height: 100px;
    overflow: hidden;
  }
}

:deep(.code-preview-dialog) {
  .el-message-box__content {
    padding: 0;
  }
  
  pre {
    margin: 0;
    padding: 12px;
    background-color: #fafafa;
    font-family: monospace;
    font-size: 14px;
    line-height: 1.5;
    white-space: pre-wrap;
    max-height: 400px;
    overflow-y: auto;
  }
}
</style> 